#include <algorithm>
#include "wingbox.h"

void wingbox::createRivets()
{
	std::for_each(top_stringers.begin(), top_stringers.end(), [this] (stringerdata& v) {
		addRivets(std::get<0>(v), std::get<1>(v), std::get<2>(v));
	});
}
void wingbox::addRivets(const stringer& s, const position& p, std::vector<double>& rivets)
{
	rivets.clear();
	double x(p.x - b.getRootClamp());
	double endx(std::max(p.x - s.getLength(), b.getTipClamp()));
	while (x > endx + poprivets.getDiameter() * 3) {
		rivets.push_back(x);
		x = nextRivet(x);
	}

	
	if (rivets.size() > 2) {
		int lastind = rivets.size() - 1;
		rivets[lastind] = (endx + poprivets.getDiameter() * 2 + rivets[lastind-1]) /2;
	}
	rivets.push_back(endx + poprivets.getDiameter() * 2);


	//double b(calcSpaceWithout(titer, pos));
	//double I(inertia(pos));
	//double c(centroid(pos));
	//double kc(getKc(pos))
}
double wingbox::nextRivet(double x) const
{
	double c(getRivetEndFixity(x));
	double E(b.getMaterial().youngsmodulus);
	double t(b.getThickness());
	double I(inertia(x));
	double f(bucklingload);
	double sweep(getSweepFactor(x));
	double s(safetyfactorrivets);
	double y(abs(centroid(x)));

	return x-std::min(sqrt((0.9 * c * E * sqr(t) * I) / (sweep * s * f * x * y)), 0.1);
}
double wingbox::getRivetEndFixity(double pos) const
{
	return poprivets.getEndFixity();
}
int wingbox::numberTotalRivets() const
{
	int totalrivets(0);
	std::for_each(top_stringers.begin(), top_stringers.end(), [this, &totalrivets] (const stringerlist::value_type& sdata) {
		totalrivets += numberTotalRivets(sdata);
	});
	return totalrivets;
}
int wingbox::numberTotalRivets(const stringerdata& sdata) const
{
	return std::get<2>(sdata).size();
}
double wingbox::weightRivets() const
{
	return poprivets.getWeight() * numberTotalRivets();
}